package com.tansun.easycare.rule.ruletest.web;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageInfo;
import com.tansun.easycare.core.utils.ResponseTable;
import com.tansun.easycare.rule.common.ResMessage;
import com.tansun.easycare.rule.common.RuleBaseController;
import com.tansun.easycare.rule.common.enums.RuleModelTypeFileEnum;
import com.tansun.easycare.rule.common.model.ResponseVO;
import com.tansun.easycare.rule.common.model.VersionModel;
import com.tansun.easycare.rule.common.service.DataBomService;
import com.tansun.easycare.rule.ruleflow.model.RuleFlowModel;
import com.tansun.easycare.rule.rulegroup.entity.RuleEntry;
import com.tansun.easycare.rule.rulegroup.entity.RuleGroup;
import com.tansun.easycare.rule.rulegroup.model.RuleGroupVO;
import com.tansun.easycare.rule.rulegroup.service.RuleEntryService;
import com.tansun.easycare.rule.rulegroup.service.RuleGroupRefService;
import com.tansun.easycare.rule.rulegroup.service.RuleGroupService;
import com.tansun.easycare.rule.rulemange.entity.RuleManage;
import com.tansun.easycare.rule.rulemange.model.RuleManageVO;
import com.tansun.easycare.rule.rulemange.service.RuleManageService;
import com.tansun.easycare.rule.ruletest.entity.RuleTest;
import com.tansun.easycare.rule.ruletest.model.RuleTestInfo;
import com.tansun.easycare.rule.ruletest.model.RuleTestMap;
import com.tansun.easycare.rule.ruletest.model.RuleTestVO;
import com.tansun.easycare.rule.ruletest.model.TestDataModeVO;
import com.tansun.easycare.rule.ruletest.service.RuleTestService;
import com.tansun.easycare.rule.ruleversion.service.RuleVersioninfoService;
import com.tansun.rule.common.RuleModelTypeEnum;
import com.tansun.rule.utils.LoggerManager;
import com.tansun.rule.utils.MClass;
import com.tansun.rule.utils.RuleBomMapXmlConvert;

@RestController
@RequestMapping(value = "/ruleProj/ruleTest")
public class RuleTestController extends RuleBaseController {

    @Autowired
    private RuleTestService ruleTestService;

    @Autowired
    private RuleManageService ruleManageService;

    @Autowired
    private RuleVersioninfoService ruleVersioninfoService;
    @Autowired
    private DataBomService dataBomService;
    @Autowired
    private RuleGroupService ruleGroupService;
    @Autowired
    private RuleGroupRefService ruleGrouprefService;
    
    @Autowired
    private RuleEntryService ruleEntryService;
    
    @RequestMapping("index")
    public ResponseTable<RuleTest> index(@RequestBody RuleTest ruleTest) throws Exception {
        ruleTest.setTestType("0");//单笔测试
        PageInfo<RuleTest> page = this.ruleTestService.findPage(ruleTest.getPage(), ruleTest);
        ResponseTable<RuleTest>  re = new ResponseTable<RuleTest>(page);
        return re;
   
    }

 


    /**
     * 测试类型选择中当选好了测试模块就会触发该事件用于输出第二选项卡中的选项内容
     */
    @RequestMapping("getRuleManageList")
    public ResponseVO
      getRuleManageList(@RequestBody RuleTestInfo  ruleTest) throws Exception {
    	ResponseVO  res = new ResponseVO();
        Map<String, Object> map = new HashMap<>();
        map.put("projectCode", ruleTest.getProjectCode());
        map.put("modelType", ruleTest.getType());
        List<RuleManageVO> list = this.ruleManageService.findRuleManageVO(map);
        res.setData(list);
        return res;

    }
    /**
     * 同上，当选好第二选项卡触发，用于输出第三选项卡的版本信息内容
     */
    @RequestMapping("getRuleVersion")
    public ResponseVO
    getRuleVersion(@RequestBody RuleTestInfo  ruleTest) throws Exception {
        List<VersionModel> verList = null;
//    	if(RuleModelTypeEnum.GeneralRule.code.equals(ruleTest.getType())) {
//    		verList = this.ruleVersioninfoService.findVersionModelList(ruleTest.getProjectCode(), ruleTest.getType(), ruleTest.getCode());
//    	}else {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("projectCode", ruleTest.getProjectCode());
            map.put("modelType",  ruleTest.getType());
            map.put("code", ruleTest.getCode());
            verList = this.ruleVersioninfoService.findVersionModelList(map);
//   	}
    	ResponseVO res = new ResponseVO();
    	res.setData(verList);
    	return res;
    }
    
    @RequestMapping("getDataMode")
    public ResponseVO getDataMode(@RequestBody RuleTestInfo  ruleTest) throws Exception {
        ResponseVO  res  = new  ResponseVO();
        if(StringUtils.isBlank(ruleTest.getProjectCode())){
            res.setStatus(100);
            res.setDescription("规则项目为空！");
            return  res;
        }
        if(StringUtils.isBlank(ruleTest.getCode())||StringUtils.isBlank(ruleTest.getType())||StringUtils.isBlank(ruleTest.getVersion())){
            res.setStatus(100);
            res.setDescription("测试类型或者版本号为空，请确认！");
            return  res;
        }
        TestDataModeVO dataModeVO = this.ruleTestService.findDataModeVO(ruleTest.getProjectCode(), ruleTest.getCode(), ruleTest.getType(), ruleTest.getVersion());
        //dataModeVO.setThenDataModelJsonString(JSON.toJSONString(dataModeVO.getThenDataModel()));
        res.setData(dataModeVO);
        return res;
    }
    
    /**
     * 点击读取按钮时触发，跳转致选取的模型页面
     */

    @RequestMapping("track")
    public String doTrack(String projectCode, String type, String version, String ruleCode,String manageId, ModelMap map, String temp) throws Exception {
        map.addAttribute("projectCode", projectCode);
        map.addAttribute("version", version);
        map.addAttribute("ruleCode", ruleCode);
        RuleManage manage = ruleManageService.getById(manageId);
        if(manage==null) {
            RuleManage condition = new RuleManage();
            condition.setCode(ruleCode);
            condition.setProjectCode(projectCode);
            List<RuleManage> list = this.ruleManageService.findList(condition);
            manage = list.get(0);
            map.addAttribute("ruleId", manage.getId());
        }
        map.put("manage", manage);
        map.addAttribute("ruleId", manage.getId());
        String fileName = RuleModelTypeFileEnum.getName(type);
        if (fileName == null) {
            fileName = "bank";
        }
        if("07".equals(type) || "17".equals(type)) {
        	RuleFlowModel model = new RuleFlowModel();
        	model.setProjectCode(projectCode);
        	model.setManageId(manage.getId());
        	model.setVersion(version);
        	model.setCode(ruleCode);
           // ruleFlowService.getRuleFlowData(model, map);
        }
        if("23".equals(type)) {
//            RuleGroup ruleGroup = new RuleGroup();
//            ruleGroup.setManageId(manage.getId());
//            ruleGroup.setVersion(version);
////            List<RuleGroup> ruleList = this.ruleGroupService.findList(ruleGroup);
//            List<RuleGroup> ruleList = this.ruleGrouprefService.findRuleGroupList(ruleGroup);
//            map.put("ruleList", ruleList);
        	fileName = "ruleEntryList";
        	RuleEntry ruleEntry = new RuleEntry();
        	ruleEntry.setManageId(manage.getId());
            ruleEntry.setVersion(manage.getVersion());
            List<RuleEntry> ruleEntryList = this.ruleEntryService.findList(ruleEntry);
            
            RuleGroup groupInfo = new RuleGroup();
            groupInfo.setManageId(manage.getId());
            groupInfo.setVersion(manage.getVersion());
            List<RuleGroup> insertList = this.ruleGrouprefService.findRuleGroupList(groupInfo);

            //组织规则集
            RuleGroupVO ruleGroupVO = new RuleGroupVO(manage,insertList,ruleEntryList);
            map.put("ruleGroupVO", ruleGroupVO);
        }
        if("21".equals(type)) {
        	RuleGroup rv = null;
	        RuleGroup ruleGroup = new RuleGroup();
	        ruleGroup.setManageId(manage.getId());
	        ruleGroup.setVersion(version);
	        List<RuleGroup> list = this.ruleGroupService.findList(ruleGroup);
	        if (list != null && list.size() > 0) {
	            rv = list.get(0);
	        }
            map.put("rv", rv);
            map.put("operType", "show");
        }
        if("01".equals(type)) {
//            Map<String, Object> reMap = decisionTreeService.getTreeInfo(ruleCode, version,this.getCurrProjectCode(),temp);
//            map.put("nodeList", JSONArray.toJSON(reMap.get("nodeList")));
//            map.put("resultItems", JSONArray.toJSON(reMap.get("resultItems")));
//            map.put("treeCode", ruleCode);
        }
        return "rule/ruletest/track/" + fileName;
    }

    /**
     * 保存
     */
    @RequestMapping("addRuelTest")
    public ResponseVO
     saveOrUpdateRuleTestAction(@RequestBody RuleTestVO ruleTest) throws Exception {
    	ResponseVO res = new ResponseVO();
        try {
            ruleTestService.saveOrUpdate(ruleTest);
        } catch (Exception e) {
        	log.error("保存单笔测试失败.",e);
            res.setStatus(ResponseVO.ERROR);
            res.setDescription("保存单笔测试失败."+e.getMessage());
        }
        return res;
    }

    @RequestMapping("updateTest")
    public ResponseVO doUpdate(@RequestBody RuleTestInfo  ruleTest) throws Exception {
        RuleTestVO ruleTestVO = ruleTestService.findRuleTestVO(ruleTest.getId());        
        ResponseVO  res  = new ResponseVO();
        res.setData(ruleTestVO);
        return res;
    }

    /**
     * 执行测试
     */
    @RequestMapping("test")
    public ResponseVO doTest(@RequestBody RuleTestMap paramData) {
        ResponseVO responseVO = new ResponseVO();
        Map<String, Object> inputMap = new HashMap<String, Object>();
        try {
            inputMap = ruleTestService.testRule(paramData, paramData.getInputJson(),paramData.getChampionInfo(),paramData.getInputParamJson());
        } catch (Exception e) {
            LoggerManager.error("", e, this.getClass());
            if (e.getCause() != null && e.getCause().getCause() != null && e.getCause().getCause() instanceof IndexOutOfBoundsException) {
                responseVO.setDescription("数组长度不够，请添加数据");
            } else {
            	Throwable root = ExceptionUtils.getRootCause(e);
    			if( root==null ) {
    				root = e;
    			}
                responseVO.setDescription("测试失败：" + root.getMessage());
                String desDetail = com.tansun.easycare.core.utils.StringUtils.toHtml(ExceptionUtils.getFullStackTrace(e));
                responseVO.setDescription(desDetail);
            }
            responseVO.setStatus(ResponseVO.ERROR);
            return responseVO;
        }
        responseVO.setData(inputMap);
        responseVO.setStatus(ResponseVO.OK);

        return responseVO;
    }

    @RequestMapping("del")
    public ResponseVO doDel(@RequestBody RuleTestInfo  ruleTest) throws Exception {
    	ResponseVO res = new ResponseVO();
        try {
            ruleTestService.delRuleTest(ruleTest.getId());
        } catch (Exception e) {
            res.setStatus(ResponseVO.ERROR);
            res.setDescription(e.getMessage());
        }
        return res;
    }

    @RequestMapping("pigeonhole")
    public ResponseVO doPigeonhole(@RequestBody RuleTestInfo  ruleTestInfo) throws Exception {
    	ResponseVO res = new ResponseVO();
        RuleTest ruleTest = this.ruleTestService.get(ruleTestInfo.getId());
        if (ruleTest != null) {
        	ruleTest.setStatus("1");
            this.ruleTestService.save(ruleTest);
        }
        return res;
    }

    /**
     * 获取全部的规则参数
     *
     * @return
     * @exception Exception
     */
    @RequestMapping("getAllParamInfo")
    public @ResponseBody
    String getAllParamInfo(String projectCode) throws Exception {
        Map<String, MClass> metaMap = this.dataBomService.findMapClass(projectCode);
        RuleBomMapXmlConvert bomMapConvert = new RuleBomMapXmlConvert();
        Map<String, Object> insertMap = bomMapConvert.buildMap(metaMap, true);
        return JSON.toJSONString(insertMap);

    }

    /**
     * 获取Drl（测试设置页面查看drl按钮触发）
     *
     * @param ruleTestInfo
     * @return
     * @exception Exception
     */
    @RequestMapping("showRuleDrl")
    public ResponseVO showRuleDrl(@RequestBody RuleTestInfo  ruleTestInfo) throws Exception {
    	ResponseVO res = new ResponseVO();
        String drl = ruleTestService.showRuleDrl(ruleTestInfo.getProjectCode(), ruleTestInfo.getCode(), ruleTestInfo.getVersion());
        drl = StringEscapeUtils.escapeXml11(drl);
        res.setData(drl);
        return res;
    }
    /**
     * 获取冠军挑战者信息（测试设置页面help按钮触发）
     *
     * @param code    规则编号
     * @param version 版本
     * @param manageId id
     * @return
     * @exception Exception
     */
    @RequestMapping("selectChallengerInfo")
    public @ResponseBody
    ResMessage selectChallengerInfo(String code, String version, String projectCode, String manageId) throws Exception {
        ResMessage res = new ResMessage();
        String challengerCode = ruleTestService.selectChallengerInfo(version,projectCode,manageId);
        res.setCode("success");
        res.setMsg(challengerCode);
        return res;
    }


}
